#include "stm32f10x_spi.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_exti.h"
#include "stm32f10x.h"
#include "CoOS.h"
#include "Config.h"
#include "stdio.h"
#include "VS1003_Audio_Decoder.h"
#include "ParseString.h"

#define Reset_VS10xx_RST	GPIO_WriteBit(VS10xx_Func_GPIO,VS10xx_RST,Bit_RESET)
#define Set_VS10xx_RST		GPIO_WriteBit(VS10xx_Func_GPIO,VS10xx_RST,Bit_SET)
#define Reset_VS10xx_CS		GPIO_WriteBit(VS10xx_Func_GPIO,VS10xx_CS,Bit_RESET)
#define Set_VS10xx_CS		GPIO_WriteBit(VS10xx_Func_GPIO,VS10xx_CS,Bit_SET)

unsigned int spi_value[10];
unsigned int value_pos = 0;
unsigned int flag_DREQ_rising = 0;
unsigned int flag_DREQ_falling = 0;

void EXTI_2_Config(void) {
	EXTI_InitTypeDef EXTI_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);

	EXTI_InitStructure.EXTI_Line = EXTI_Line12;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);
}

void VS10xx_Func_Config(void) {
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_VS10xx_Func_ClockCmd;
	GPIO_InitStructure.GPIO_Pin = VS10xx_CS | VS10xx_RST;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(VS10xx_Func_GPIO, &GPIO_InitStructure);
}

void SPI_VS10xx_Config(void) {
	GPIO_InitTypeDef GPIO_InitStructure;
	SPI_InitTypeDef SPI_InitStructure;
	RCC_SPI_VS10xx_ClockCmd;
	//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
	//	RCC_APB2PeriphClockCmd(RCC_APB1Periph_SPI1, ENABLE);
	//CONFIG SPI1 MASTER CLK, MOSI
	GPIO_InitStructure.GPIO_Pin = SPI_VS10xx_CLK | SPI_VS10xx_MOSI;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(SPI_VS10xx_GPIO, &GPIO_InitStructure);
	//CONFIG SPI1 MISO
	GPIO_InitStructure.GPIO_Pin = SPI_VS10xx_MISO;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(SPI_VS10xx_GPIO, &GPIO_InitStructure);
	//SPI2 CONFIG
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	SPI_Init(SPI_VS10xx, &SPI_InitStructure);
	SPI_Cmd(SPI_VS10xx, ENABLE);
	//SPI_NSSInternalSoftwareConfig(SPI_VS10xx, SPI_NSSInternalSoft_Set);
	SPI_I2S_ITConfig(SPI_VS10xx, SPI_I2S_IT_RXNE, ENABLE);
}

unsigned int DREQ_Status(void) {
	if (GPIO_ReadInputDataBit(VS10xx_Func_GPIO, VS10xx_DREQ) == Bit_RESET) {
		return 0;
	} else {
		return 1;
	}
}

void SPI_VS10xx_Send(uint8_t data) {
	SPI_I2S_SendData(SPI_VS10xx, data);
}

uint16_t SPI_VS10xx_Get(void) {
	return SPI_I2S_ReceiveData(SPI_VS10xx);
}

void SPI2_IRQHandler(void) {
	//CoEnterISR();
	if (SPI_I2S_GetITStatus(SPI_VS10xx, SPI_I2S_IT_RXNE) == SET) {
		spi_value[value_pos++] = SPI_I2S_ReceiveData(SPI_VS10xx);
		SPI_I2S_ClearITPendingBit(SPI_VS10xx, SPI_I2S_IT_RXNE);
	}
	//CoExitISR();
}

void EXTI15_10_IRQHandler(void) {
	if (EXTI_GetITStatus(EXTI_Line12) == SET) {
		flag_DREQ_rising++;
		EXTI_ClearITPendingBit(EXTI_Line12);
	}
}

void HardReset_VS10xx(void) {
	Reset_VS10xx_RST;
	delayms(100);
	Set_VS10xx_RST;
	Set_VS10xx_CS;
	puts("wait for DREQ go low and high\r\n");
	while (flag_DREQ_rising == 0) {
	}
	printf("flag_DREQ_rising = %u\r\n", flag_DREQ_rising);
}

void SoftReset_VS10xx(void) {
	while (flag_DREQ_rising == 0) {
	}
	flag_DREQ_rising = 0;
	puts("start soft reset\r\n");
	Reset_VS10xx_CS;
	SPI_VS10xx_Send(0x02);
	SPI_VS10xx_Get();
	SPI_VS10xx_Send(0x00);
	SPI_VS10xx_Get();
	SPI_VS10xx_Send(0x00);
	SPI_VS10xx_Get();
	SPI_VS10xx_Send(0x04);
	SPI_VS10xx_Get();
	Set_VS10xx_CS;
	while (flag_DREQ_rising == 0) {
	}
	printf("flag_DREQ_rising = %u\r\n", flag_DREQ_rising);
}

void Test_Beep_VS10xx(void) {
	while (flag_DREQ_rising == 0)
		;
	flag_DREQ_rising = 0;
	Reset_VS10xx_CS;
	SPI_VS10xx_Send(0x2);
	SPI_VS10xx_Get();
	SPI_VS10xx_Send(0x0);
	SPI_VS10xx_Get();
	SPI_VS10xx_Send(0xc);
	SPI_VS10xx_Get();
	SPI_VS10xx_Send(0x20);
	SPI_VS10xx_Get();
	Set_VS10xx_CS;
	puts("start test beep\r\n");
	while (1) {
		puts("loop1\r\n");
		SPI_VS10xx_Send(0x53);
		SPI_VS10xx_Get();
		SPI_VS10xx_Send(0xEF);
		SPI_VS10xx_Get();
		SPI_VS10xx_Send(0x6E);
		SPI_VS10xx_Get();
		SPI_VS10xx_Send(0x44);
		SPI_VS10xx_Get();
		SPI_VS10xx_Send(0x0);
		SPI_VS10xx_Get();
		SPI_VS10xx_Send(0x0);
		SPI_VS10xx_Get();
		SPI_VS10xx_Send(0x0);
		SPI_VS10xx_Get();
		SPI_VS10xx_Send(0x0);
		SPI_VS10xx_Get();
		puts("loop2\r\n");
		delayms(500);
		puts("loop3\r\n");
		SPI_VS10xx_Send(0x45);
		SPI_VS10xx_Get();
		SPI_VS10xx_Send(0x78);
		SPI_VS10xx_Get();
		SPI_VS10xx_Send(0x69);
		SPI_VS10xx_Get();
		SPI_VS10xx_Send(0x74);
		SPI_VS10xx_Get();
		puts("loop4\r\n");
		delayms(500);
		puts("loop5\r\n");
	}
}

void VS10xx_SetVol(void) {
	while (flag_DREQ_rising == 0) {
	}
	flag_DREQ_rising = 0;
	puts("start set vol\r\n");
	Reset_VS10xx_CS;
	SPI_VS10xx_Send(0x02);
	printf("get = %u\r\n", SPI_VS10xx_Get());
	SPI_VS10xx_Send(0x0b);
	printf("get = %u\r\n", SPI_VS10xx_Get());
	SPI_VS10xx_Send(0xa5);
	printf("get = %u\r\n", SPI_VS10xx_Get());
	SPI_VS10xx_Send(0xe5);
	printf("get = %u\r\n", SPI_VS10xx_Get());
	Set_VS10xx_CS;
	while (flag_DREQ_rising == 0)
		;
}

void VS10xx_GetVol(void) {
	uint16_t tmp1 = 0, tmp2 = 0;
	while (flag_DREQ_rising == 0) {
	}
	flag_DREQ_rising = 0;
	Reset_VS10xx_CS;
	SPI_VS10xx_Send(0x03);
	printf("get = %u\r\n", SPI_VS10xx_Get());
	SPI_VS10xx_Send(0x0b);
	printf("get = %u\r\n", SPI_VS10xx_Get());
	SPI_VS10xx_Send(0x01);
	printf("get = %u\r\n", SPI_VS10xx_Get());
	SPI_VS10xx_Send(0x01);
	printf("get it = %u\r\n", SPI_VS10xx_Get());
	printf("get it = %u\r\n", SPI_VS10xx_Get());
	Set_VS10xx_CS;
	OUTPUT_USARTTerm;
	printf("DREQ count:%u\r\n", flag_DREQ_rising);
}
